/**
 * gvSIG. Desktop Geographic Information System.
 *
 * Copyright (C) 2007-2012 gvSIG Association.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA  02110-1301, USA.
 *
 * For any additional information, do not hesitate to contact us
 * at info AT gvsig.com, or visit our website www.gvsig.com.
 */
package org.gvsig.titleblock.impl;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.HashMap;

import javax.swing.JPanel;

import org.gvsig.andami.Launcher;
import org.gvsig.andami.PluginServices;
import org.gvsig.app.ApplicationLocator;
import org.gvsig.app.ApplicationManager;
import org.gvsig.app.project.documents.layout.fframes.FFramePicture;
import org.gvsig.app.project.documents.layout.fframes.FFrameText;
import org.gvsig.app.project.documents.layout.fframes.IFFrame;
import org.gvsig.titleblock.IFFrames;
import org.gvsig.titleblock.ITBManager;
import org.gvsig.titleblock.ITBToFFrame;
import org.gvsig.tools.ToolsLocator;
import org.gvsig.tools.i18n.I18nManager;
import org.gvsig.tools.persistence.PersistenceManager;
import org.gvsig.tools.persistence.PersistentState;
import org.gvsig.tools.persistence.exception.PersistenceException;

/**
 * Represents the transformation of a TitleBlock into a FFrame
 * 
 * @author Violeta Carlos
 * @version $Id$
 */
public class TBToFFrame implements ITBToFFrame {
	
	private ITBManager manager;
	private I18nManager i18nmanager;
	private PersistenceManager persistManager;
	private ApplicationManager applicationManager;
	private IFFrames fframes;

	/**
	 * Sets the variables
	 * @param manager
	 */
	public TBToFFrame(ITBManager manager) {
		this.manager = manager;
		this.i18nmanager = ToolsLocator.getI18nManager();
		this.persistManager = ToolsLocator.getPersistenceManager();
		this.applicationManager = ApplicationLocator.getManager(); 
		
	}
	
	/**
	 * Converts a gvb file into a Frame
	 */
	public void gvbToFrames(File file, HashMap<String, String> selecteds) {
		
		try {
			fframes = load(file);
		} catch (PersistenceException e) {
			fframes = null;
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			fframes = null;
			e.printStackTrace();
		}
		if (fframes == null)
			return;
		IFFrame[] frames=fframes.getFframes();
		manager.getLayout().getLayoutContext().getFrameCommandsRecord().startComplex(PluginServices.getText(this,"box"));

		IFFrame[] fframes = manager.getLayout().getLayoutContext().getFFrames();
		for (int i = fframes.length - 1; i >= 0; i--) {
			IFFrame fframe1 = fframes[i];
			fframe1.setSelected(false);
		}

		for (int i = 0; i < frames.length; i++) {
			String tag=frames[i].getTag();
			if (tag != null){
				String value=selecteds.get(tag);
				if (value!=null){
					if (frames[i] instanceof FFrameText){
						FFrameText text = (FFrameText)frames[i];
						text.clearText();
						text.addText(value);
						AffineTransform at = manager.getLayout().getLayoutContext().getAT();
						double myScale = at.getScaleX() * 0.0234; // FLayoutUtilities.fromSheetDistance(folio.getAncho(),at)/rv.getWidth();

		               int scaledFontSize = 0;
						// Distinguish when the font has fixed size or not
		               Rectangle2D.Double raux = text.getBoundingBox(at);
		               String m_text = ((String)text.getText().get(0)); 
		               if (text.isFontSizeFixed()) {
		                    scaledFontSize = (int) (text.getFontSize()*myScale);
		                    if (((raux.width) / m_text.length())<scaledFontSize){
		                    	 scaledFontSize = (int) ((raux.width / m_text.length()));
		                    	 text.setFontSize(scaledFontSize);
		                    }
		                    
		               } 

					} else if (frames[i] instanceof FFramePicture){
						((FFramePicture)frames[i]).load(value);
					}
				}
			}
			manager.getLayout().getLayoutContext().addFFrame(frames[i],false, true);
		}
		manager.getLayout().getLayoutContext().getFrameCommandsRecord().endComplex();
	}

	/**
	 * Loads a gvb file
	 * @param file
	 * @return
	 * @throws FileNotFoundException
	 * @throws PersistenceException
	 */
	private IFFrames load(File file) throws FileNotFoundException, PersistenceException{
		InputStream in = new FileInputStream(file);
		PersistentState state2 = persistManager.loadState(in);
		IFFrames fframes = (IFFrames) persistManager.create(state2);
		return fframes;
	}
	
	/**
	 * Gets all the items of the file
	 */
	public Object[] getItems() {
		String path=Launcher.getApplicationDirectory()+File.separator+"Boxes";
        File boxFiles=new File(path);
        if (boxFiles.exists()){
            return boxFiles.listFiles();
        }
        return new Object[]{};
	}

	/**
	 * Checks if the file has filled tags
	 */
	public boolean hasTags(File file) {
		try {
			fframes = load(file);
		} catch (PersistenceException e) {
			fframes = null;
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			fframes = null;
			e.printStackTrace();
		}
		
		if (fframes == null)
			return false;		

		IFFrame[] frames=fframes.getFframes();
		for (int i = 0; i < frames.length; i++) {
			if (frames[i].getTag()!=null){
				return true;
			}
		}
		return false;
	}
	
	/**
	 * This method tests if the tag is present in the array of frames that we are working with
	 * @param tagName
	 * @return
	 */
	public boolean hasThisTag (String tagName) {
		
		IFFrame[] frames = fframes.getFframes();
		
		for (int i = 0; i < frames.length; i++) {
			if(frames[i].getTag()!=null && frames[i].getTag().equals(tagName)) {
				return true;
			}
		}
		
		return false;
	
	}

	public ITBManager getManager() {
		return manager;
	}
	
	@Override
	public void drawInPanel(JPanel jpanel, Graphics graphics) {
		
		if (fframes == null)
			return;
//		Graphics graphics = jpanel.getGraphics();
		
		graphics.clearRect(0, 0, jpanel.getWidth(), jpanel.getHeight());
		graphics.setColor(Color.white);
		graphics.fillRect(0, 0, jpanel.getWidth(), jpanel.getHeight());
		IFFrame[] frames=fframes.getFframes();
		Rectangle2D r = null;
		AffineTransform at = new AffineTransform();
		for (int i = 0; i < frames.length; i++) {
			if (r==null){
				r = (Rectangle2D)frames[i].getBoundingBox(at).clone();
			}else{
				r.add(frames[i].getBoundingBox(at));
			}
		}
		
		Rectangle2D rectPanel = new Rectangle2D.Double(0, 0, jpanel.getWidth(), jpanel.getHeight());
		AffineTransform atPanel = new AffineTransform();
		AffineTransform escalado = new AffineTransform();
        AffineTransform translacion = new AffineTransform();
        translacion.setToTranslation(-r.getMinX(), -r.getMinY());
        double scaleX = rectPanel.getWidth()/r.getWidth();
		double scaleY = rectPanel.getHeight()/r.getHeight();
        escalado.setToScale(scaleX, scaleY);
        atPanel.setToIdentity();
        atPanel.concatenate(escalado);
        atPanel.concatenate(translacion);
 		
		for (int i = 0; i < frames.length; i++) {
			frames[i].draw((Graphics2D)graphics, atPanel, rectPanel, null);
		}
	}
}
